package com.phuc.game.tankshooter.sprite;

import java.util.ArrayList;

import org.anddev.andengine.entity.IEntity;
import org.anddev.andengine.entity.modifier.ParallelEntityModifier;
import org.anddev.andengine.entity.modifier.PathModifier;
import org.anddev.andengine.entity.modifier.PathModifier.IPathModifierListener;
import org.anddev.andengine.entity.modifier.PathModifier.Path;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.util.MathUtils;
import org.anddev.andengine.util.constants.TimeConstants;

import android.util.Log;

import com.phuc.game.tankshooter.MainActivity;
import com.phuc.game.tankshooter.engine.GamePlay;

public class ItemSprite extends AnimatedSprite implements TimeConstants {

	public static ArrayList<ItemSprite> listItemSprites = new ArrayList<ItemSprite>();
	
	private static final int SIZE = 70;
	public static final int TYPE_HEART = 3400;
	public static final int TYPE_ROCKET = 3401;
	public static final int TYPE_ROCKET_BIG = 3402;
	public static final int TYPE_DEAD = 3403;
	public static final int TYPE_POINT = 3404;
	
	int heartAdd = 0;
	int rocketAdd = 0;
	int rocketBigAdd = 0;
	int pointAdd = 0;
	int type;
	
	Path path;
	float speed;
	ParallelEntityModifier movingModifier;
	
	float scale;
	float alpha;
	
	boolean canbeAttacked;
	
	public ItemSprite(int type, TiledTextureRegion pTiledTextureRegion) {
		super(-SIZE, -SIZE, SIZE, SIZE, pTiledTextureRegion);
		this.type = type;
		switch (type) {
		case TYPE_HEART:
			heartAdd = 1;
			break;
		case TYPE_ROCKET:
			rocketAdd = 5;
			break;
		case TYPE_ROCKET_BIG:
			rocketBigAdd = 1;
			break;
		case TYPE_DEAD:
			heartAdd = -1;
			break;
		case TYPE_POINT:
			pointAdd = 10;
			break;
		default:
			break;
		}
		
		isIncrease = false;
		canbeAttacked = true;
		scale = 1.0f;
		alpha = 1.0f;
		listItemSprites.add(this);
		move();
	}
	
	public void attacked(float x1, float y1, int range) {
		if (!canbeAttacked) {
			return;
		}
		
		int rangeTmp = range;
		
		float thisX = (this.getX() + SIZE / 2);
		float thisY = (this.getY() + SIZE / 2);
		
		float rangeX = thisX - x1;
		float rangeY = thisY - y1;
		
		float rangeBetweenRocketAndObject = 
				(float) Math.sqrt((rangeX * rangeX + rangeY * rangeY));
		if (rangeBetweenRocketAndObject < rangeTmp) {
			Log.d("phucphuc", "phucphuc attack item good" );
			GamePlay game = MainActivity.getInstant().getGamePlay();
			game.addPoint(pointAdd);
			game.decreaseLife(-heartAdd);
			game.addRocketNumTotal(rocketAdd);
			game.addRocketBigNum(rocketBigAdd);
			canbeAttacked = false;
			this.unregisterEntityModifier(movingModifier);
			move();
		}
	}
	
	public void move() {
		// create random path
		if (canbeAttacked) {
			createRandomPath();
		} else {
			createFinishPath();
		}
		
		// Move
		PathModifier pm = new PathModifier(speed, path, null,
				new IPathModifierListener() {

					@Override
					public void onPathStarted(PathModifier pPathModifier,
							IEntity pEntity) {
					}

					@Override
					public void onPathWaypointStarted(
							PathModifier pPathModifier, IEntity pEntity,
							int pWaypointIndex) { }

					@Override
					public void onPathWaypointFinished(
							PathModifier pPathModifier, IEntity pEntity,
							int pWaypointIndex) { }

					@Override
					public void onPathFinished(PathModifier pPathModifier,
							final IEntity pEntity) {
						finishMoving();
					}
				});
		movingModifier = new ParallelEntityModifier(pm);
		this.registerEntityModifier(movingModifier);
	}
	
	private void createRandomPath() {
		speed = 3;
		int numberOfPath = MathUtils.random(3, 5);
		Log.d("phucphuc", "phucphuc item " + numberOfPath);
		boolean startFromLeft = MathUtils.random(0, 1) == 1;
		int randX;
		int randY;
		int startX = -SIZE;
		int endX = MainActivity.SCENE_WIDTH;
		randY = MathUtils.random(100, MainActivity.SCENE_HEIGH - 400);
		if (!startFromLeft) {
			Log.d("phucphuc", "phucphuc item start from right");
			startX = MainActivity.SCENE_WIDTH;
			endX = -SIZE;
		}
		
		path = new Path(numberOfPath).to(startX, randY);
		Log.d("phucphuc", "phucphuc item : " + startX + "; " + randY);
		
		for (int i = 1; i < numberOfPath - 1; i++) {
			randX = MathUtils.random(100, MainActivity.SCENE_WIDTH - 100);
			randY = MathUtils.random(100, MainActivity.SCENE_HEIGH - 400);
			path = path.to(randX, randY);
			Log.d("phucphuc", "phucphuc item : " + randX + "; " + randY);
		}
		randY = MathUtils.random(100, MainActivity.SCENE_HEIGH - 400);
		path = path.to(endX, randY);	
		Log.d("phucphuc", "phucphuc item : " + endX + "; " + randY);
	}

	private void createFinishPath() {
		speed = 0.3f;
		float startX = this.getX();
		float startY = this.getY();
		float endX = MainActivity.SCENE_WIDTH / 2 - SIZE / 2;
		float endY = MainActivity.SCENE_END_LOCATION;
		
		switch (type) {
		case TYPE_HEART:
			endX = MainActivity.SCENE_WIDTH / 2 - SIZE / 2;
			endY = MainActivity.SCENE_END_LOCATION;
			break;
		case TYPE_ROCKET:
			endX = SIZE;
			endY = MainActivity.SCENE_HEIGH - SIZE;
			break;
		case TYPE_ROCKET_BIG:
			endX = MainActivity.SCENE_WIDTH - SIZE;
			endY = MainActivity.SCENE_HEIGH - SIZE;
			break;
		case TYPE_DEAD:
			endX = MainActivity.SCENE_WIDTH - SIZE;
			endY = SIZE;
			break;
		case TYPE_POINT:
			endX = SIZE;
			endY = SIZE;
			break;
		default:
			break;
		}
		path = new Path(2).to(startX, startY).to(endX, endY);
	}
	
	protected void finishMoving() {
		MainActivity.getInstant().runFromUpdateThread(new Runnable() {
			@Override
			public void run() {
				listItemSprites.remove(ItemSprite.this);
				ItemSprite.this.detachSelf();
				ItemSprite.this.setIgnoreUpdate(true);
				ItemSprite.this.clearEntityModifiers();
				ItemSprite.this.clearUpdateHandlers();
			}
		});
	}
	
	boolean isIncrease;
	
	@Override
	public void onManagedUpdate(final float pSecondsElapsed) {
		super.onManagedUpdate(pSecondsElapsed);
		
		if (!canbeAttacked) {
			scale -= 0.04;
			this.setScale(scale);
			alpha -= 0.04;
			this.setAlpha(alpha);
		} else {
			if (isIncrease) {
				alpha += 0.05;
				if (alpha >= 1) {
					isIncrease = false;
				}
			} else {
				alpha -= 0.05;
				if (alpha <= 0.2) {
					isIncrease = true;
				}
			}
			
			this.setAlpha(alpha);
		}
	}
}
